package com.dtborad.myblog.controller;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.dtborad.myblog.common.BCSendEmailUtil;
import com.dtborad.myblog.common.CommonErrorCode;
import com.dtborad.myblog.common.Result;
import com.dtborad.myblog.dto.UserDto;
import com.dtborad.myblog.entity.*;
import com.dtborad.myblog.service.EmailService;
import com.dtborad.myblog.service.UserService;
import io.swagger.annotations.Api;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.catalina.User;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.*;

@RestController
@RequestMapping("/user")
@Slf4j
@Api(tags = "用户模块")
@CrossOrigin(origins = "*")
public class UserController {

    @Autowired
    private UserService userService;

    @Autowired
    private EmailService emailService;

    @GetMapping
    public Result<List<Users>> getUserAll() {
        List<Users> usersList = userService.list();
        return Result.ofSuccess(usersList);
    }

    //分页查询
    @GetMapping("/list")
    public Result<Map<String, Object>> getUserList(@RequestParam(defaultValue = "1") int pagenum,
                                                   @RequestParam(defaultValue = "5") int pagesize,
                                                   @RequestParam(defaultValue = "") String username,
                                                   @RequestParam(defaultValue = "") String nickname) {
        Page<Users> currentPage = userService.getAllUserByPageSize(pagenum, pagesize, username, nickname);
        Map<String, Object> response = new HashMap<>();
        response.put("records", currentPage.getRecords());
        response.put("total", currentPage.getTotal());
        return Result.ofSuccess(response);
    }

    @GetMapping("/{id}")
    public Result<Users> getUserById(@PathVariable Integer id) {
        LambdaQueryWrapper<Users> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Users::getUsersid, id);
        Users user = userService.getOne(wrapper);
        if (user != null) {
            return Result.ofSuccess(user);
        } else {
            return Result.ofFail(CommonErrorCode.DATA_NOT_FOUND);
        }
    }

    //登录
    @PostMapping("/login")
    public Result<Users> login(@RequestBody Users user) {
        try {
            //查询用户是否存在
            LambdaQueryWrapper<Users> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(Users::getUsername, user.getUsername());
            Users users = userService.getOne(wrapper);
            if (users != null) {
                if (users.getStatus() == 0) {
                    //判断密码是否正确
                    if (users.getPassword().equals(user.getPassword())) {
                        return Result.ofSuccess(users);
                    }
                } else {
                    return Result.ofFail("444", "该账号已被封禁，请联系管理员");
                }
            }
        } catch (Exception e) {
            //e.printStackTrace();
            return Result.ofFail(CommonErrorCode.BAD_REQUEST);
        }
        return Result.ofFail(CommonErrorCode.LOGIN_FAIL);
    }

    //注册
    @PostMapping("/register")
    public Result<String> register(@RequestBody Users user) {
        Integer i = 0;
        try {
            user.setRegisterTime(new Date());
            i = userService.registerUser(user);
        } catch (Exception e) {
            return Result.ofFail(CommonErrorCode.DATA_CONFLICT);
        }
        if (i > 0) {
            return Result.ofSuccess();
        }
        return Result.ofFail(CommonErrorCode.FAILURE);
    }

    //修改账号信息
    @PostMapping("/update")
    public Result<Users> updateUserInfo(@RequestBody UserDto userDto) {
        System.out.println(userDto);
        try {
            LambdaQueryWrapper<Users> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(Users::getUsername, userDto.getUsername()).eq(Users::getPassword, userDto.getPassword());
            Users one = userService.getOne(wrapper);
            if (one != null) {
                //判断属性是否为空, 不为空则修改
                if (StrUtil.isNotBlank(userDto.getNickname())) one.setNickname(userDto.getNickname());
                if (StrUtil.isNotBlank(userDto.getEmail())) one.setEmail(userDto.getEmail());
                if (StrUtil.isNotBlank(userDto.getAvatarPath())) one.setAvatarPath(userDto.getAvatarPath());
                if (StrUtil.isNotBlank(userDto.getNewpassword())) one.setPassword(userDto.getNewpassword());
                BeanUtils.copyProperties(userDto, one);
            }
            userService.update(one, wrapper);
            return Result.ofSuccess();
        } catch (Exception e) {
            return Result.ofFail(CommonErrorCode.FAILURE);
        }
    }

    //忘记密码
    @PostMapping("/forget")
    public Result<String> forgetPassword(@RequestBody UserDto userDto) {
        try {
            //检验账号和邮箱是否匹配
            LambdaQueryWrapper<Users> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(Users::getUsername, userDto.getUsername()).eq(Users::getEmail, userDto.getEmail());
            Users one = userService.getOne(wrapper);
            if (one != null) {
                //修改密码
                one.setPassword(userDto.getPassword());
                boolean update = userService.update(one, wrapper);
                if (update) return Result.ofSuccess();
            }
        } catch (Exception e) {
            return Result.ofFail(CommonErrorCode.FAILURE);
        }
        return Result.ofFail(CommonErrorCode.FAILURE);
    }

    // 发送邮件并生成邮箱验证码
    @PostMapping("/sendEmail")
    public Result<Email> sendEmail(@RequestBody UserDto userDto) {
        try {
            // 检验账号和邮箱是否匹配
            LambdaQueryWrapper<Users> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(Users::getUsername, userDto.getUsername()).eq(Users::getEmail, userDto.getEmail());
            Users one = userService.getOne(wrapper);
            if (one != null) {
                // 发送邮件并生成验证码
                BCSendEmailUtil sendEmailUtil = new BCSendEmailUtil();
                StringBuilder content = new StringBuilder();
                Random random = new Random();
                String code = String.format("%04d", random.nextInt(10000));
                content.append("尊敬的用户，您好！\n\n");
                content.append("您正在进行邮箱验证码校验操作。\n");
                content.append("验证码为: " + code + "\n\n");
                content.append("请在页面中输入该验证码以完成验证。\n\n");
                content.append("如果您未进行此操作，请忽略此邮件。\n");
                sendEmailUtil.sendMail(userDto.getEmail(), "重置密码", content.toString(), null);
                Email email = new Email();
                email.setEmail(userDto.getEmail());
                email.setCode(code);
                email.setCreated_at(new Date());
                email.setCount(5);//重试次数最多5次
                //检查当前邮箱是否已存在验证码
                LambdaQueryWrapper<Email> lqw = new LambdaQueryWrapper<>();
                lqw.eq(Email::getEmail, userDto.getEmail());
                List<Email> list = emailService.list(lqw);
                if (list != null && list.size() > 0) {
                    emailService.update(email, lqw);
                } else {
                    emailService.save(email);
                }
                return Result.ofSuccess(email);
            }
        } catch (Exception e) {
            return Result.ofFail(CommonErrorCode.FAILURE);
        }
        return Result.ofFail(CommonErrorCode.SERVICE_UNAVAILABLE);
    }

    //校验邮箱验证码
    @PostMapping("/verifyCode")
    public Result<String> checkEmailCode(@RequestBody UserDto userDto) {
        try {
            //获取验证码
            String email = userDto.getEmail();
            String code = userDto.getCode();
            LambdaQueryWrapper<Email> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(Email::getEmail, email).eq(Email::getCode, code);
            Email one = emailService.getOne(wrapper);
            if (one != null && one.getCount() > 0) {
                emailService.remove(wrapper);//校验完成, 移除库中存在的验证码, 避免重复使用
                return Result.ofSuccess();
            } else {
                //验证码错误, 重试次数-1
                LambdaQueryWrapper<Email> lqw = new LambdaQueryWrapper<>();
                lqw.eq(Email::getEmail, email);
                Email now = emailService.getOne(lqw);
                if (now != null) {
                    if (now.getCount() > 0) {
                        now.setCount(now.getCount() - 1);
                        emailService.update(now, lqw);
                        return Result.ofFail("400", "验证码错误", String.valueOf(now.getCount()));
                    } else {
                        emailService.remove(lqw);
                        return Result.ofFail("500", "重试次数达到限制");
                    }

                }
                return Result.ofFail(CommonErrorCode.DATA_NOT_FOUND);
            }
        } catch (Exception e) {
            return Result.ofFail(CommonErrorCode.FAILURE);
        }
    }

    //修改用户状态(0: 启用, 1: 禁用)
    @PostMapping("/status")
    public Result<Void> updateStatus(@RequestBody UserDto userDto) {
        try {
            LambdaQueryWrapper<Users> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(Users::getUsername, userDto.getUsername());
            Users one = userService.getOne(wrapper);
            if (one != null) {
                one.setStatus(userDto.getStatus());
                userService.update(one, wrapper);
                return Result.ofSuccess();
            }
        } catch (Exception e) {
            return Result.ofFail(CommonErrorCode.FAILURE);
        }
        return Result.ofFail(CommonErrorCode.DATA_CONFLICT);
    }
}
